home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
WINDOWS
/
OLE_101.ARJ
/
OLELINK1.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-13
|
29KB
|
951 lines
/*
* OLELINK1.C
*
* Functions to handle the Edit Links command as well as the
* Links dialog.
*
* Copyright(c) Microsoft Corp. 1992 All Rights Reserved
*/
#include <windows.h>
#include <ole.h>
#include "register.h"
#include "oclient.h"
/*
* FOLELinksEdit
*
* Purpose:
* Handles the Links dialog and the Update Now, Cancel Link, and
* Change Link commands.
*
* Parameters:
* hWnd HWND of the parent window.
* hInst HANDLE of the application instance.
* pDoc LPDOCUMENT to OLE information.
*
* Return Value:
* BOOL FALSE if we could not create the dialog or if
* the user pressed Cancel. TRUE otherwise.
*/
BOOL FAR PASCAL FOLELinksEdit(HWND hWnd, HANDLE hInst, LPDOCUMENT pDoc)
{
FARPROC lpfn;
WORD wRet;
lpfn=MakeProcInstance(LinksProc, hInst);
wRet=DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_LINKS), hWnd,
lpfn, (LONG)pDoc);
FreeProcInstance(lpfn);
return (1==wRet);
}
/*
* LinksProc
*
* Purpose:
* Dialog procedure for the Links dialog.
*
* Parameters:
* The standard.
*
* Return Value:
* The value to be returned through the DialogBox call that
* created the dialog.
*/
BOOL FAR PASCAL LinksProc(HWND hDlg, WORD iMsg, WORD wParam, LONG lParam)
{
static LPDOCUMENT pDoc;
HWND hList;
WORD cxTabs[3];
RECT rc;
WORD cx;
DWORD dwBase;
OLEOPT_UPDATE dwUpdate;
hList=GetDlgItem(hDlg, ID_LINKLIST);
switch (iMsg)
{
case WM_INITDIALOG:
pDoc=(LPDOCUMENT)lParam;
pDoc->hList=hList;
//Initialize tabstops, each at 1/4 of the listbox width.
GetClientRect(hList, &rc);
//Pixel width of a tab. Put in pDoc->cxList for CchListStringCreate.
pDoc->cxList=((rc.right-rc.left) >> 2)-8;
//Convert pixel width to dialog width for LB_SETTABSTOPS
dwBase=GetDialogBaseUnits();
cx=((rc.right-rc.left) * 4)/LOWORD(dwBase);
cxTabs[0]=cx >> 2;
cxTabs[1]=cx >> 1;
cxTabs[2]=(cx * 3) >> 2;
SendMessage(hList, LB_SETTABSTOPS, 3, (LONG)(LPSTR)&cxTabs);
//Initialize listbox strings.
if (!FObjectsEnumerate(pDoc, FEnumLinksInit, 0L))
EndDialog(hDlg, -1);
//Select the first listbox string.
SendMessage(hList, LB_SETSEL, 1, 0L);
EnableLinkButtons(hDlg, hList);
return TRUE;
case WM_COMMAND:
switch (wParam)
{
case ID_UPDATENOW:
/*
* If we're updating, just enumerate selected links and
* let FEnumLinkUpdate take care of finding other matching
* unselected links and updating them.
*/
FLinksEnumerate(hList, pDoc, FEnumLinkUpdate,
ENUMLINK_SELECTED, MAKELONG(0, IDOK));
//Insure that the fNoMatch flags are reset.
FLinksEnumerate(hList, pDoc, FEnumLinkUpdate, ENUMLINK_ALL,
MAKELONG(0, IDCANCEL));
EnableLinkButtons(hDlg, hList);
break;
case ID_CANCELLINK:
FLinksEnumerate(hList, pDoc, FEnumLinkCancel,
ENUMLINK_SELECTED, 0L);
EnableLinkButtons(hDlg, hList);
break;
case ID_CHANGELINK:
FChangeLinks(hList, pDoc);
EnableLinkButtons(hDlg, hList);
break;;
case ID_UPDATEAUTO:
case ID_UPDATEMANUAL:
dwUpdate=(ID_UPDATEAUTO==wParam) ? oleupdate_always : oleupdate_oncall;
if (0L!=SendMessage(LOWORD(lParam), BM_GETCHECK, 0, 0L))
{
FLinksEnumerate(hList, pDoc, FEnumOptionChange,
ENUMLINK_SELECTED, dwUpdate);
EnableLinkButtons(hDlg, hList);
}
break;
case ID_LINKLIST:
if (HIWORD(lParam) == LBN_SELCHANGE)
EnableLinkButtons(hDlg, hList);
break;
case IDCANCEL:
FLinksEnumerate(hList, pDoc, FEnumLinksUndo,
ENUMLINK_ALL, 0L);
EndDialog(hDlg, FALSE);
break;
case IDOK:
FLinksEnumerate(hList, pDoc, FEnumLinksAccept,
ENUMLINK_ALL, 0L);
EndDialog(hDlg, TRUE);
break;
}
break;
}
return FALSE;
}
/*
* FEnumLinksInit
*
* Purpose:
* For each enumerated object that is linked we build a listbox string
* for it and add it to a listbox (the handle is found in pDoc->hList).
*
* Parameters:
* pDoc LPDOCUMENT identifying the owner of all objects.
* pObj LPOBJECT identifying the current object.
* dw DWORD for extra data, unused.
*
* Return Value:
* BOOL TRUE--we want to enumerate everything.
*/
BOOL FAR PASCAL FEnumLinksInit(LPDOCUMENT pDoc, LPOBJECT pObj, DWORD dw)
{
static WORD iClone=0; //Counter for clone objects.
WORD i;
char szClone[40];
OLESTATUS os;
if (OT_LINK==pObj->dwType)
{
/*
* We already have the ObjectLink data in ATOMs, so just pass the
* object to CchLinkStringCreate.
*/
CchLinkStringCreate(pDoc->pszData1, pDoc, pObj);
i=(WORD)SendMessage(pDoc->hList, LB_ADDSTRING, 0, (LONG)pDoc->pszData1);
SendMessage(pDoc->hList, LB_SETITEMDATA, i, (LONG)(LPSTR)pObj);
//Create a clone name
wsprintf(szClone, "Clone #%d", iClone);
//Clone the object for Undo on Cancel.
os=OleClone(pObj->pObj, (LPOLECLIENT)pObj, pDoc->lh, szClone, &pObj->pObjUndo);
//Wait for any one object.
pDoc->cWait=0;
OsError(os, pDoc, pObj, FALSE);
FOLEReleaseWait(TRUE, pDoc, NULL);
//Save the open state of this object.
os=OleQueryOpen(pObj->pObj);
pObj->fUndoOpen=(OLE_OK==os);
//Mark this object as clean
pObj->fLinkChange=FALSE;
}
iClone++;
return TRUE;
}
/*
* FChangeLinks
*
* Purpose:
* Retrieve a new link filename from the user and change selected links
* to that new file. Then scan the remaining unselected links and ask
* the user to change those as well. All links will be from the same
* original file since the Change Link button is otherwise disabled.
*
* Parameters:
* hList HWND to the listbox of link items.
* pDoc LPDOCUMENT containing OLE information.
*
* Return Value:
* BOOL TRUE if the function was successful, FALSE on an error
* or if the user pressed Cancel.
*/
BOOL FAR PASCAL FChangeLinks(HWND hList, LPDOCUMENT pDoc)
{
LPSTR pszLinkFile;
LPSTR pszFile;
LPSTR pszExt;
LPSTR psz;
HANDLE hInst;
HWND hWndParent;
BOOL fRet;
ATOM aFileOld;
ATOM aFileNew;
WORD cch;
WORD wTemp;
char szFile[CCHPATHMAX];
hWndParent=GetParent(hList);
hInst=GetWindowWord(hWndParent, GWW_HINSTANCE);
//Find the first selected item and retrieve its ObjectLink data
FLinksEnumerate(hList, pDoc, FEnumLinkFind, ENUMLINK_SELECTED,
MAKELONG(1, 1));
//Chew out a filename from this thing.
pszFile =pDoc->pszData1 + lstrlen(pDoc->pszData1) + 1;
lstrcpy(szFile, pszFile);
aFileOld=AddAtom(pszFile);
DeleteAtom(aFileOld);
/*
* Before calling FFileDialog to show the Common Dialog in which
* we retrieve a new link name, we need to produce one extension
* string for the currently linked file and produce a Filter string
* like "Excel Worksheet (.XLS)." As of 1/27/92 the UI spec shows
* the application name in the filter combobox, but we have no way
* of getting that from an extension, unless we're to parse WIN.INI
* which is out of the question.
*/
//Get a pointer to the extension.
pszExt=PszExtensionFromFile(pszFile);
/*
* Create a filter using the extension name with the . If there
* is no association between the file extension and a classname
* and descriptive name in the registration DB, then the two calls
* into REGISTER.C fail and we just list the extension itself.
* That's about the best we can do.
*/
WClassFromExtension(pszExt, pDoc->pszData2, CCHPATHMAX);
WDescriptionFromClass(pDoc->pszData2, pDoc->pszData1, CCHPATHMAX);
wsprintf(pDoc->pszData2, " (%s)", pszExt);
lstrcat(pDoc->pszData1, pDoc->pszData2);
//Skip the . in the extension if we have one.
if ('.'==*pszExt)
pszExt++;
fRet=FFileDialog(hWndParent, hInst, pszExt, pDoc->pszData1,
szFile, PSZOLE(IDS_CHANGELINK), TRUE);
//Stop if the user cancelled.
if (!fRet)
return FALSE;
//Go change the selected links and update them.
aFileNew=AddAtom(szFile);
FLinksEnumerate(hList, pDoc, FEnumLinkChange,
ENUMLINK_SELECTED, MAKELONG(aFileNew, 0));
FLinksEnumerate(hList, pDoc, FEnumLinkUpdate, ENUMLINK_SELECTED,
MAKELONG(0, IDIGNORE));
//Find an unselected link that matches.
fRet=FLinksEnumerate(hList, pDoc, FEnumLinkFind,
ENUMLINK_UNSELECTED, MAKELONG(aFileOld, 0));
if (fRet)
{
DeleteAtom(aFileNew);
return TRUE;
}
//Ask the user if they want to update the rest to szFile.
psz=pDoc->pszData2;
pszLinkFile=PszFileFromPath(szFile);
GetAtomName(pDoc->aFile, pDoc->pszData3, CCHPATHMAX);
pszFile=PszFileFromPath(pDoc->pszData3);
cch=wsprintf(psz, PSZOLE(IDS_CHANGELINKS1), pszLinkFile, pszFile);
wsprintf(psz+cch, PSZOLE(IDS_CHANGELINKS2), pszLinkFile);
//Ask to update additional links.
wTemp=MessageBox(hWndParent, psz, PSZOLE(IDS_CHANGELINK),
MB_YESNO | MB_ICONEXCLAMATION);
//If they say yes, then find unselected links that match and change them.
if (IDYES==wTemp)
{
FLinksEnumerate(hList, pDoc, FEnumLinkChange,
ENUMLINK_UNSELECTED, MAKELONG(aFileNew, aFileOld));
//We have to change the search ATOM since we changed the link.
aFileOld=aFileNew;
//Update these changed links.
FLinksEnumerate(hList, pDoc, FEnumLinkUpdate, ENUMLINK_UNSELECTED,
MAKELONG(aFileOld, IDIGNORE));
}
DeleteAtom(aFileNew);
return TRUE;
}
/*
* FLinksEnumerate
*
* Purpose:
* Walks through each items in the list. If the object is selected
* (or NOT selected) and the object is NOT static, then we call a
* provided function of type LPFNLINKENUM.
*
* If the enumeration function should always wait for each object. This
* enumeration function will not wait for all objects at the end.
*
* Parameters:
* hList HWND of the listbox with the link items
* pDoc LPDOCUMENT containing OLE information.
* pfn LPFNOBJECTENUM to the function to call for
* each item.
* wSelection WORD indicating the type of links to enumerate, either
* ENUMLINK_SELECTED, ENUMLINK_UNSELECTED, or ENUMLINK_ALL.
* dwData DWORD extra data to pass to the enumeration
* function.
*
* Return Value:
* BOOL TRUE if we processed all listbox items, FALSE
* if the enumeration function stopped it.
*/
BOOL FAR PASCAL FLinksEnumerate(HWND hList, LPDOCUMENT pDoc, LPFNLINKENUM pfn,
WORD wSelection, DWORD dwData)
{
WORD cLinks;
LPOBJECT pObj;
WORD i;
BOOL fSel;
BOOL fRet=TRUE;
cLinks=(WORD)SendMessage(hList, LB_GETCOUNT, 0, 0L);
//Loop through the items update non-static ones.
for (i=0; i < cLinks; i++)
{
//Get the selection state of the item
fSel=(BOOL)SendMessage(hList, LB_GETSEL, i, 0L);
//Get the data pointer for this item.
pObj=(LPOBJECT)SendMessage(hList, LB_GETITEMDATA, i, 0L);
//Match the item found to the type desired and call the callback.
if (ENUMLINK_ALL!=wSelection && OT_STATIC==pObj->dwType)
continue;
if ((fSel && ENUMLINK_SELECTED==wSelection) ||
(!fSel && ENUMLINK_UNSELECTED==wSelection) ||
(ENUMLINK_ALL==wSelection))
{
//Call the enumeration function
if (!(*pfn)(hList, i, pDoc, pObj, dwData))
{
fRet=FALSE;
break;
}
}
}
return fRet;
}
/*
* FEnumOptionChange
*
* Purpose:
* Enumeration function for changing selected list items between manual
* and automatic.
*
* Parameters:
* hList HANDLE to the links listbox.
* i WORD index of the item affected.
* pDoc LPDOCUMENT containing OLE information
* pObj LPOBJECT of the currently enumerated object.
* dw DWORD application supplied extra data
*
* Return Value:
* BOOL Always TRUE since we want to process all selected
* items.
*/
BOOL FAR PASCAL FEnumOptionChange(HWND hList, WORD i, LPDOCUMENT pDoc,
LPOBJECT pObj, DWORD dw)
{
OLESTATUS os;
/*
* dw contains the type of link we're changing to, so if this item
* already matches we can skip it.
*/
if ((OLEOPT_UPDATE)dw==pObj->dwLink)
return TRUE;
/*
* For any item that changes, call OleSetLinkUpdateOptions
* to change the link option, change it in the OBJECT structure,
* and rebuild the string in the list. Only the link option
* changes in the object; none of the string nor atoms change.
*/
pObj->dwLink=(OLEOPT_UPDATE)dw;
os=OleSetLinkUpdateOptions(pObj->pObj, (OLEOPT_UPDATE)dw);
/*
* We can wait for release later since we won't do any more
* OLE with this object. This depends on CchLinkStringCreate NOT
* calling any OLE functions.
*/
if (OLE_OK==OsError(os, pDoc, pObj, TRUE))
{
CchLinkStringCreate(pDoc->pszData1, pDoc, pObj);
LinkStringChange(hList, i, pDoc->pszData1);
pObj->fLinkChange=TRUE;
}
return TRUE;
}
/*
* FEnumLinkUpdate
*
* Purpose:
* Immediately updates a selected links. If dw!=0L then the LOWORD
* contains an ATOM to compare to link names stored in the objects.
* If HIWORD is zero, then any object that matches is updated--otherwise
* just compare the atom to the link in the object and mark it as
* needing update later.
*
* Parameters:
* hList HANDLE to the links listbox.
* i WORD index of the item affected.
* pDoc LPDOCUMENT containing OLE information
* pObj LPOBJECT of the currently enumerated object.
* dw DWORD application supplied extra data.
*
* Return Value:
* BOOL Always TRUE since we want to process all selected
* items.
*/
BOOL FAR PASCAL FEnumLinkUpdate(HWND hList, WORD i, LPDOCUMENT pDoc,
LPOBJECT pObj, DWORD dw)
{
LPSTR psz;
LPSTR pszLinkFile;
LPSTR pszFile;
BOOL fRet;
WORD wTemp;
DWORD dwT;
WORD cch;
HWND hWndParent;
OLESTATUS os;
switch (HIWORD(dw))
{
case IDIGNORE:
if (0!=LOWORD(dw))
{
//Skip items that do not match.
if (LOWORD(dw)!=pObj->aLink)
return TRUE;
}
break;
case IDRETRY:
/*
* We only use this for selected items...if the links match, set
* fNoMatch so we don't try to find matching unselected links
* later.
*/
if (LOWORD(dw)==pObj->aLink)
pObj->fNoMatch=TRUE;
return TRUE;
case IDCANCEL:
//Clear pObj->fNoMatch
pObj->fNoMatch=FALSE;
return TRUE;
}
os=OleUpdate(pObj->pObj);
os=OsError(os, pDoc, pObj, TRUE);
//Mark the object as changed.
pObj->fLinkChange=TRUE;
/*
* If update failed, mark as unavailable. Otherwise change unavailable
* links back to automatic.
*/
dwT=pObj->dwLink;
if (OLE_OK!=os)
pObj->dwLink=OLEUPDATE_UNAVAILABLE;
else
{
if (OLEUPDATE_UNAVAILABLE==pObj->dwLink)
pObj->dwLink=oleupdate_always;
}
//Change the listbox if the option changed.
if ((DWORD)pObj->dwLink!=dwT)
{
CchLinkStringCreate(pDoc->pszData1, pDoc, pObj);
LinkStringChange(hList, i, pDoc->pszData1);
}
//If we were just updating, we can leave now.
if (IDIGNORE==HIWORD(dw))
return TRUE;
/*
* If we already updated other unselected links for this file, then
* don't ask the user again. We change this flag for selected items
* the first time we update unselected matching items.
*/
if (pObj->fNoMatch)
return TRUE;
//Find any unselected link that matches this file.
fRet=FLinksEnumerate(hList, pDoc, FEnumLinkFind,
ENUMLINK_UNSELECTED, MAKELONG(pObj->aLink, 0));
//If fRet is TRUE, there were no other matches.
if (fRet)
return TRUE;
/*
* If we found a match, display a message asking if we want to update
* unselected links that match.
*/
//Ask the user if they want to update the rest to szFile.
GetAtomName(pObj->aLink, pDoc->pszData1, CBSCRATCH);
pszLinkFile=PszFileFromPath(pDoc->pszData1);
cch=lstrlen(pDoc->pszData1)+1;
GetAtomName(pDoc->aFile, pDoc->pszData1+cch, CBSCRATCH-cch);
pszFile=PszFileFromPath(pDoc->pszData1+cch);
psz=pDoc->pszData2;
cch=wsprintf(psz, PSZOLE(IDS_UPDATELINKS1), pszLinkFile, pszFile);
wsprintf(psz+cch, PSZOLE(IDS_UPDATELINKS2), pszLinkFile);
hWndParent=GetParent(hList);
wTemp=MessageBox(hWndParent, psz, PSZOLE(IDS_UPDATEMSG), MB_YESNO | MB_ICONEXCLAMATION);
/*
* Mark all matching SELECTED files so we don't try to ask the
* user again for the same file. This marks the one we're currently
* looking at, but that's not a problem.
*/
FLinksEnumerate(hList, pDoc, FEnumLinkUpdate, ENUMLINK_SELECTED,
MAKELONG(pObj->aLink, IDRETRY));
//Update all matching unselected links.
if (IDYES==wTemp)
{
FLinksEnumerate(hList, pDoc, FEnumLinkUpdate, ENUMLINK_UNSELECTED,
MAKELONG(pObj->aLink, IDIGNORE));
}
return TRUE;
}
/*
* FEnumLinkCancel
*
* Purpose:
* Uses OleObjectConvert to change a linked object to a static object.
* Note that this is much like the FEnumOptionChange function as it
* changes an object to static instead of automatic or manual.
*
* Parameters:
* hList HANDLE to the links listbox.
* i WORD index of the item affected.
* pDoc LPDOCUMENT containing OLE information
* pObj LPOBJECT of the currently enumerated object.
* dw DWORD application supplied extra data
*
* Return Value:
* BOOL Always TRUE since we want to process all selected
* items.
*/
BOOL FAR PASCAL FEnumLinkCancel(HWND hList, WORD i, LPDOCUMENT pDoc,
LPOBJECT pObj, DWORD dw)
{
OLESTATUS os;
LPOLEOBJECT pOLEObj;
/*
* For any item that we cancel, call OleObjectConvert, set
* the dwLink field in the OBJECT to OLEUPDATE_STATIC, and delete the
* old object. After this we can update the listbox to reflect the
* cancelled link.
*/
GetAtomName(pObj->aName, pDoc->pszData1, 80);
os=OleObjectConvert(pObj->pObj, PSZOLE(IDS_STATIC), (LPOLECLIENT)pObj,
pDoc->lh, pDoc->pszData1, &pOLEObj);
if (OLE_OK!=os)
return TRUE;
//Delete the old object and wait on it.
os=OleDelete(pObj->pObj);
if (OLE_OK==OsError(os, pDoc, pObj, TRUE))
{
//Set the new object in this window.
pObj->pObj = pOLEObj;
pObj->dwLink = -1;
pObj->dwType = OT_STATIC;
CchLinkStringCreate(pDoc->pszData1, pDoc, pObj);
LinkStringChange(hList, i, pDoc->pszData1);
pObj->fLinkChange=TRUE;
}
return TRUE;
}
/*
* FEnumLinkChange
*
* Purpose:
* Changes the link data for an item, simply by calling FObjectDataGet
* and then FObjectDataSet, which in turn calls OleSetData.
*
* Parameters:
* hList HANDLE to the links listbox.
* i WORD index of the item affected.
* pDoc LPDOCUMENT containing OLE information
* pObj LPOBJECT of the currently enumerated object.
* dw DWORD application supplied extra data. The LOWORD
* is an ATOM containing the update filename. If HIWORD
* is zero, we just update. If it's non-zero then
* HIWORD is an ATOM containing the file to match
* before updating. This latter use is for updating
* non-selected links that match.
*
* Return Value:
* BOOL Always TRUE since we want to process all items.
*/
BOOL FAR PASCAL FEnumLinkChange(HWND hList, WORD i, LPDOCUMENT pDoc,
LPOBJECT pObj, DWORD dw)
{
/*
* If we're updating non-selected links, check if the files match
* and skip if they don't. We have no bother to check selected
* links since the Change Link... button is grayed if all the selected
* items in the list are not linked to the same file.
*/
if (0!=HIWORD(dw))
{
if ((ATOM)HIWORD(dw)!=pObj->aLink)
return TRUE;
}
//Get the new link filename.
GetAtomName(LOWORD(dw), pDoc->pszData1, CCHPATHMAX);
//Change this item's data and update the string
if (FObjectDataSet(pDoc, pObj, pDoc->cfObjectLink, pDoc->pszData1))
{
//Changing an unavailable link makes it automatic by default.
if (OLEUPDATE_UNAVAILABLE==pObj->dwLink)
pObj->dwLink=oleupdate_always;
CchLinkStringCreate(pDoc->pszData1, pDoc, pObj);
LinkStringChange(hList, i, pDoc->pszData1);
pObj->fLinkChange=TRUE;
}
return TRUE;
}
/*
* FEnumLinkFind
*
* Purpose:
* If the HIWORD of dw is 0, then this function compares an ATOM
* containing a filename to the provided ATOM in the LOWORD of dw to
* that stored in the object. If they match, then the ObjectLink data
* for the file is stored in pDoc->szData1 and this function returns FALSE,
* stopping the enumeration.
*
* If HIWORD(dw) is non-zero, we just get data for the first object we get.
*
* Parameters:
* hList HANDLE to the links listbox.
* i WORD index of the item affected.
* pDoc LPDOCUMENT containing OLE information
* pObj LPOBJECT of the currently enumerated object.
* dw DWORD application supplied extra data.
*
* Return Value:
* BOOL Always TRUE since we want to process all selected
* items.
*/
BOOL FAR PASCAL FEnumLinkFind(HWND hList, WORD i, LPDOCUMENT pDoc,
LPOBJECT pObj, DWORD dw)
{
//Continue enumeration if the atoms do not match.
if (0==HIWORD(dw))
{
if ((ATOM)LOWORD(dw)!=pObj->aLink)
return TRUE;
}
FObjectDataGet(pObj, pDoc->cfObjectLink, pDoc->pszData1);
return FALSE;
}
/*
* FEnumLinksUndo
*
* Purpose:
* Checks if the object was modified in the links dialog and restores
* its original state if so from the cloned object. The object now stored
* in the OBJECT structure is deleted with OleDelete. If it was originally
* open to a server, it is reconnected.
*
* Parameters:
* hList HANDLE to the links listbox.
* i WORD index of the item affected.
* pDoc LPDOCUMENT containing OLE information
* pObj LPOBJECT of the currently enumerated object.
* dw DWORD application supplied extra data.
*
* Return Value:
* BOOL Always TRUE since we want to process all selected
* items.
*/
BOOL FAR PASCAL FEnumLinksUndo(HWND hList, WORD i, LPDOCUMENT pDoc,
LPOBJECT pObj, DWORD dw)
{
OLESTATUS os;
char szObject[128];
//For unmodified links, nuke the clone.
if (!pObj->fLinkChange)
{
/*
* Note that in waiting for release we watch the fRelease flag
* in pObj, not the OLEOBJECT within the structure. Since we
* called OleClone with the same OBJECT in which its stored, we'll
* get that OBJECT in the CallBack when we do release, if you
* just set a flag like Patron does.
*/
os=OleDelete(pObj->pObjUndo);
OsError(os, pDoc, pObj, TRUE);
return TRUE;
}
//Get the name of the object for OleRename on the clone.
GetAtomName(pObj->aName, szObject, 128);
//Delete the old object.
os=OleDelete(pObj->pObj);
os=OsError(os, pDoc, pObj, TRUE);
if (OLE_OK!=os)
return TRUE;
pObj->pObj=pObj->pObjUndo;
pObj->pObjUndo=NULL;
//Do this before reinitializing since the initializer calls OleQueryName.
OleRename(pObj->pObj, szObject);
//Reinitialize this object's cache information.
PObjectInitialize(pObj, pDoc);
//Attempt to reestablish a lost link for the clone.
if (pObj->fUndoOpen)
{
os=OleReconnect(pObj->pObj);
OsError(os, pDoc, pObj, TRUE); //Wait
}
/*
* This is a little sleazy, using the CallBack method for this object
* to force a repaint. But it's actually kosher since the DS register
* will be correct (CallBack does not change it) and prevents us from
* having to find where this object is otherwise stored (as in a window).
*/
(*pObj->pvt->CallBack)((LPOLECLIENT)pObj, OLE_CHANGED, pObj->pObj);
return TRUE;
}
/*
* FEnumLinksAccept
*
* Purpose:
* Clean up any cloned objects when we accept changes in the Links dialog.
*
* Parameters:
* hList HANDLE to the links listbox.
* i WORD index of the item affected.
* pDoc LPDOCUMENT containing OLE information
* pObj LPOBJECT of the currently enumerated object.
* dw DWORD application supplied extra data.
*
* Return Value:
* BOOL Always TRUE since we want to process all selected
* items.
*/
BOOL FAR PASCAL FEnumLinksAccept(HWND hList, WORD i, LPDOCUMENT pDoc,
LPOBJECT pObj, DWORD dw)
{
OLESTATUS os;
os=OleDelete(pObj->pObjUndo);
os=OsError(os, pDoc, pObj, TRUE);
return TRUE;
}